﻿//-----------------------------------------------------------------------
// Source File: "SourceFolder.cs"
// Create Date: 07/30/2014 10:16 AM
// Last Updated: 07/30/2014 10:16 AM
// Authors(s): nealbailey@hotmail.com
//-----------------------------------------------------------------------
// GNU GENERAL PUBLIC LICENSE
//-----------------------------------------------------------------------
// Revision: Version 3, 29 June 2007
// Copyright © 2007 Free Software Foundation, Inc. http://fsf.org/
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//  GNU General Public License for more details.
//  REFERENCE: http://www.gnu.org/licenses/
//-----------------------------------------------------------------------
// Copyright (c) 2010-2014 Baileysoft Solutions
//-----------------------------------------------------------------------
namespace Baileysoft.Gaming.Utils.Yasm
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text;

    /// <summary>
    /// Encapsulation object for working with the <see cref="SourceFolder"/> part of a user-defined folder pair
    /// </summary>
    public class SourceFolder
    {
        #region Constructors

        /// <summary>
        /// Constructor.
        /// </summary>
        public SourceFolder()
            : this(string.Empty)
        {
        }

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="path">The full folder path.</param>
        public SourceFolder(string path)
        {
            Path = path;
            JunctionPointTarget = string.Empty;
            FolderName = GetFolderName();
        }

        #endregion Constructors

        #region Properties

        /// <summary>
        /// The folder name (without the path).
        /// </summary>
        public virtual string FolderName
        {
            get; set;
        }

        /// <summary>
        /// The readable sum of all the file sizes of all files in the folder (recursive)
        /// <para>This is set from the GetReadableFileSize method.</para>
        /// </summary>
        public virtual string FormattedSize
        {
            get; set;
        }

        /// <summary>
        /// The target of the junction-point.
        /// <para>This must be set externally.</para>
        /// </summary>
        public virtual string JunctionPointTarget
        {
            get; set;
        }

        /// <summary>
        /// The full path to the folder.
        /// </summary>
        public virtual string Path
        {
            get; set;
        }

        /// <summary>
        /// The collective sum of all the file sizes of all files in the folder (recursive)
        /// <para>This is set from the GetDirectorySize method.</para>
        /// </summary>
        public virtual long Size
        {
            get; protected set;
        }

        #endregion Properties

        #region Methods

        /// <summary>
        /// Calculate the directory size, based on the sum of all the files in the folder.
        /// </summary>
        /// <returns><see cref="long"/></returns>
        /// <exception cref="System.ArgumentException">searchPattern contains one or more invalid characters defined by the <see cref="M:System.IO.Path.GetInvalidPathChars" /> method. </exception>
        /// <exception cref="System.ArgumentNullException">searchPattern is null. </exception>
        /// <exception cref="System.ArgumentOutOfRangeException">searchOption is not a valid <see cref="T:System.IO.SearchOption" /> value.</exception>
        /// <exception cref="System.IO.DirectoryNotFoundException">The path is invalid (for example, it is on an unmapped drive). </exception>
        /// <exception cref="System.Security.SecurityException">The caller does not have the required permission. </exception>
        /// <exception cref="System.OverflowException">The sum is larger than <see cref="F:System.Int64.MaxValue" />.</exception>
        protected internal virtual long GetDirectorySize()
        {
            if (string.IsNullOrEmpty(Path))
                return 0;

            Size = new DirectoryInfo(Path).GetFiles("*", SearchOption.AllDirectories).Sum(file => file.Length);
            return Size;
        }

        /// <summary>
        /// Gets the folder name (without the path).
        /// </summary>
        /// <returns><see cref="string"/></returns>
        protected internal virtual string GetFolderName()
        {
            if (string.IsNullOrEmpty(Path))
                return string.Empty;

            if (!Directory.Exists(Path))
                return string.Empty;

            return new DirectoryInfo(Path).Name;
        }

        /// <summary>
        /// Convert the <see cref="long"/> file size to readable string.
        /// </summary>
        /// <returns><see cref="string"/></returns>
        /// <exception cref="System.ArgumentNullException">The exception that is thrown when a null reference (Nothing in Visual Basic) is passed to a method that does not accept it as a valid argument.</exception>
        /// <exception cref="System.FormatException">The exception that is thrown when the format of an argument does not meet the parameter specifications of the invoked method.</exception>
        protected internal virtual string GetReadableFileSize()
        {
            return GetReadableFileSize(Size);
        }

        /// <summary>
        /// Convert the <see cref="long"/> file size to readable string.
        /// </summary>
        /// <returns><see cref="string"/>. A friendly, readable file size string.</returns>
        /// <exception cref="System.ArgumentNullException">The exception that is thrown when a null reference (Nothing in Visual Basic) is passed to a method that does not accept it as a valid argument.</exception>
        /// <exception cref="System.FormatException">The exception that is thrown when the format of an argument does not meet the parameter specifications of the invoked method.</exception>
        protected internal virtual string GetReadableFileSize(long fileSize)
        {
            if (string.IsNullOrEmpty(Path))
                return string.Empty;

            if (!Directory.Exists(Path))
                return string.Empty;

            if (fileSize == 0)
                fileSize = GetDirectorySize();

            double sizeKb = (Convert.ToDouble(fileSize) / 1024);
            double sizeMb = sizeKb / 1024;
            double sizeGb = sizeMb / 1024;
            double sizeTb = sizeGb / 1024;

            var resultString = String.Format("{0} TB", Math.Round(sizeTb, 2));

            if (sizeTb < 1)
                resultString = String.Format("{0} GB", Math.Round(sizeGb, 2));

            if (sizeGb < 1)
                resultString = String.Format("{0} MB", Math.Round(sizeMb), 2);

            if (sizeMb < 1)
                resultString = String.Format("{0} KB", Math.Round(sizeKb), 2);

            if (sizeKb < 1)
                resultString = String.Format("{0} bytes", fileSize);

            return resultString;
        }

        #endregion Methods
    }
}